import { MenuModel } from '../../schemas/system/Menu';
import { Menu } from '../../types';
import { HttpError } from '../../exceptions/HttpError';

export class MenuRepository {
  // 获取所有菜单
  async findAll(): Promise<Menu[]> {
    try {
      return await MenuModel.find().sort({ sort: -1 }).populate('createdBy updatedBy tenantId').lean();
    } catch (error: any) {
      throw HttpError.internalServerError(`获取菜单列表失败: ${error.message}`);
    }
  }



  // 根据ID获取菜单
  async findById(id: string): Promise<Menu | null> {
    try {
      const menu = await MenuModel.findById(id).populate('createdBy updatedBy tenantId').lean();
      if (!menu) {
        throw HttpError.notFound('菜单不存在');
      }
      return menu;
    } catch (error: any) {
      if (error instanceof HttpError) throw error;
      throw HttpError.internalServerError(`获取菜单信息失败: ${error.message}`);
    }
  }



  // 创建菜单
  async create(menuData: Partial<Menu>): Promise<Menu> {
    try {
      const menu = new MenuModel(menuData);
      return await menu.save();
    } catch (error: any) {
      if (error.code === 11000) {
        throw HttpError.conflict('菜单已存在');
      }
      if (error.name === 'ValidationError') {
        throw HttpError.unprocessableEntity('数据验证失败1', error.errors);
      }
      throw HttpError.internalServerError(`创建菜单失败: ${error.message}`);
    }
  }

  // 更新用户
  async update(id: string, menuData: Partial<Menu>): Promise<Menu | null> {
    try {
      // 移除密码字段，防止通过更新接口修改密码
      const { ...updateData } = menuData;

      const menu = await MenuModel.findByIdAndUpdate(
        id,
        updateData,
        { new: true, runValidators: true }
      );

      if (!menu) {
        throw HttpError.notFound('菜单不存在');
      }

      return menu;
    } catch (error: any) {
      if (error instanceof HttpError) throw error;
      if (error.code === 11000) {
        throw HttpError.conflict('菜单已存在');
      }
      if (error.name === 'ValidationError') {
        throw HttpError.unprocessableEntity('数据验证失败', error.errors);
      }
      throw HttpError.internalServerError(`更新菜单失败: ${error.message}`);
    }
  }

  // 删除菜单
  async delete(id: string): Promise<boolean> {
    try {
      const result = await MenuModel.findByIdAndDelete(id);
      if (!result) {
        throw HttpError.notFound('菜单不存在');
      }
      return true;
    } catch (error: any) {
      if (error instanceof HttpError) throw error;
      throw HttpError.internalServerError(`删除菜单失败: ${error.message}`);
    }
  }

  // 获取菜单数量
  async count(): Promise<number> {
    try {
      return await MenuModel.countDocuments();
    } catch (error: any) {
      throw HttpError.internalServerError(`统计菜单数量失败: ${error.message}`);
    }
  }

  // 分页查询菜单
  async findWithPagination(page: number = 1, limit: number = 10): Promise<{ list: Menu[], page: number, limit: number, total: number, pages: number }> {
    try {
      const skip = (page - 1) * limit;
      const [list, total] = await Promise.all([
        MenuModel.find().sort({ sort: -1 }).skip(skip).limit(limit).populate('createdBy updatedBy tenantId').lean(),
        MenuModel.countDocuments()
      ]);
      return {
        list,
        total,
        page,
        limit,
        pages: Math.ceil(total / limit)
      };
    } catch (error: any) {
      throw HttpError.internalServerError(`分页查询菜单失败: ${error.message}`);
    }
  }
}

export default new MenuRepository();
